home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / cool.lha / ice / papers / cool-core.ms next >
Text File  |  1991-09-04  |  45KB  |  886 lines

  1. .nr PS 10
  2. .nr VS 12
  3. .nr PD .7v
  4. .nr LL 6.5i
  5. .TL
  6. COOL \*- C++ Object-Oriented Library 
  7. .AU
  8. Mary Fontana
  9. LaMott Oren
  10. .AI
  11. Texas Instruments Incorporated
  12. Computer Science Center
  13. Dallas, TX
  14. .AU
  15. Martin Neath
  16. .AI
  17. Texas Instruments Incorporated
  18. Information Technology Group
  19. Austin, TX
  20. .NH 1
  21. Introduction
  22. .LP
  23. The C++ Object-Oriented Library (COOL) is a collection of 
  24. classes, templates, and macros for use by C++ programmers writing complex 
  25. applications. It raises the level of abstraction for the programmer to 
  26. concentrate on the problem domain, not on implementing base data structures, 
  27. macros, and classes. In addition, COOL also provides a system independent 
  28. software platform on top of which applications are built, since COOL 
  29. encapsulates such system specific functionality as date/time and exception 
  30. handling. This paper discusses the following COOL features:
  31. .ID
  32. \(bu Preprocessor and macros
  33. \(bu Parameterized templates
  34. \(bu Symbols and Packages
  35. \(bu Polymorphic management
  36. \(bu Exception handling
  37. \(bu Coding style and conventions
  38. \(bu Class hierarchy and overview
  39. .DE
  40. COOL is the first piece of what is expected to be an ever changing and
  41. growing C++ class library. As such, some constraints will be necessary in order
  42. to achieve compatible and seamless integration of new or modified features.
  43. This paper outlines the major technologies and conventions that can be used and
  44. followed to allow this to happen. This paper should be used as an aid in
  45. understanding the COOL library, its organization, structure, and layout.
  46. It assumes the reader to have a working knowledge of C++[1].  For more detailed
  47. information and examples on each topic, the reader is referred to the
  48. appropriate section(s) of the COOL User's manual[2].
  49. .NH 1
  50. Preprocessor and Macros
  51. .LP
  52. The COOL macro facility is an extension to the standard ANSI C macro
  53. preprocessing functions available with the #define statement. The COOL
  54. preprocessor is a modified tokenizing ANSI C preprocessor that allows a
  55. programmer to define powerful extensions to the C++ language in an unobtrusive
  56. manner. This enhanced preprocessor is portable and compiler independent and can
  57. execute arbitrary filter programs or macro expanders on C++ code fragments.
  58. Macros such as those that support parameterized templates are implementations
  59. of theoretical design papers published by Bjarne Stroustrup[3]. Others provide
  60. significant language features and enhanced power for the programmer heretofore
  61. unavailable with conventional C++ implementations. It is important to note,
  62. however, that once a macro is expanded, the resulting code is conventional C++
  63. 2.0 syntax acceptable to any conforming C++ translator or compiler[4].
  64.  
  65. The COOL preprocessor is supplied as part of the library and is the point at 
  66. which all language and computing enhancements available in COOL are 
  67. implemented. The proposed draft ANSI C standard indicates that extensions and 
  68. changes to the language and/or features implemented in a preprocessor/compiler 
  69. should be made by using the #pragma statement. The COOL preprocessor follows 
  70. this recommendation and uses this as the means by which all macro extensions 
  71. are made. The #pragma defmacro statement is the single hook through which 
  72. features such as the class macro, parameterized templates, and polymorphic 
  73. enhancements have been implemented.
  74.  
  75. The COOL preprocessor is derived from and based upon the DECUS ANSI C 
  76. preprocessor made available by the DEC User's group in the public domain and 
  77. supplied on the X11R3 source tape from MIT. It complies with the draft ANSI C 
  78. specification with the exception that trigraph sequences are not implemented. 
  79. In addition to support for COOL macro processing discussed above, the 
  80. preprocessor has several new command line options to support C++ comments and 
  81. includes file debugging aids.
  82.  
  83. The #pragma defmacro statement is implemented in the COOL C/C++ preprocessor
  84. and is the single hook through which features such as the class macro,
  85. parameterized templates, and polymorphic enhancements have been implemented.
  86. The defmacro facility provides a way to execute arbitrary filter programs on
  87. C++ code fragments passing through the preprocessor. When a defmacro style
  88. macro name is found, the name and everything until the delimiter (including all
  89. matching {} [] () <> #" `' and comments found along the way) is piped onto the
  90. standard input stream of the indicated program or filter procedure. The
  91. procedure's standard output is scanned by the preprocessor for further
  92. processing. The expansion replaces the macro call and is passed onto the
  93. compiler for parsing.
  94.  
  95. The implementation of a defmacro can be either external to the preprocessor (as
  96. in the case of files and programs) or internal to the preprocessor. For
  97. example, the template, declare and implement macros that implement
  98. parameterized types is internal to the preprocessor to provide a more efficient
  99. implementation. The defmacro facility first searches for a file or program in
  100. the same search path as that used for include files. If a match is not found,
  101. an internal preprocessor table is searched. If a match is still not found, the
  102. error message, "Error: Cannot open macro file [xxx]", where xxx is the name as
  103. it appears in the source code, is sent to the standard error stream.  The
  104. fundamental COOL macros are defined with defmacro in the header file
  105. <COOL/misc.h>, which must be included in any COOL C++ source file.
  106.  
  107. Porting COOL to a new platform or operating system starts with the
  108. preprocessor. The preprocessor contains support for the defmacro statement and
  109. also implements several important macros internally for efficiency and
  110. performance considerations. In addition, a powerful macro language, simplifying
  111. many library functions is available via the \fBMACRO\fR keyword.
  112. \fBMACRO\fR implements an enhanced #define syntax that supports
  113. multiple line, arbitrary length, nested macros and preprocessor directives with
  114. positional, optional, optional keyword, required keyword, rest, and body
  115. arguments. Many of the COOL features would be very difficult, if not
  116. impossible, to implement without this enhanced macro language.
  117. .NH 1
  118. Parameterized Templates
  119. .LP
  120. The development and successful deployment of application libraries such as COOL
  121. is made easier and more useful by a language feature called
  122. parameterization.  Parameterized templates allow a programmer to design and
  123. implement a class template without specifying the data type. The user
  124. customizes the template to produce a specific class by indicating the type in a
  125. program. Several versions of the same parameterized template (each with a
  126. different type) can exist in a single application. Parameterized templates can
  127. be thought of as meta-classes in that only one source base needs to be
  128. maintained to support numerous variations of a type of class.
  129.  
  130. Regardless of the type of object a parameterized class is to manipulate, the
  131. structure and organization of the class and the implementation of the member
  132. functions are the same for every version of the class. For example, a
  133. programmer providing a vector class knows that there will be several member
  134. functions such as insert, remove, print, sort, and so on that apply to every
  135. version of the class. By parameterizing the arguments and return values from
  136. the various member functions, the programmer provides only one implementation
  137. of the vector class. The user of the class then specifies the type of vector at
  138. compile-time.
  139.  
  140. An important and useful type of parameterized template is known as a container
  141. class. A container class is a special kind of parameterized class where you put
  142. objects of a particular type. For example, the \fBVector\fR<\fIType\fR>,
  143. \fBList\fR<\fIType\fR>, and \fBHash_Table\fR<\fIKType,Vtype\fR> classes are
  144. container classes because they contain a set of programmer-defined data types.
  145. Since container classes are so commonplace in many applications and programs,
  146. parameterized container classes provide a mechanism to maintain one source base
  147. for several versions of very useful data structures. COOL supplies several
  148. common container class data structures that can be used in many typical
  149. application scenarios.
  150.  
  151. Each of the COOL parameterized container classes support the notion of a
  152. built-in iterator that maintains a current position in the container and is
  153. updated by various member functions. These member functions allow you to move
  154. through the collection of objects in some order and manipulate the element
  155. value at that position. This might be used, for example, in a function that
  156. takes a pointer to a generic object that is a type of container object. The
  157. function can iterate through the elements in the container by using the current
  158. position member functions without needing to know whether the object is a
  159. vector, a list, or a queue.
  160.  
  161. In addition to this built-in current position mechanism, COOL provides
  162. support for multiple iterators over the same class by using the \fBIterator
  163. \fR<\fIType\fR> class. For example, a programmer may need to
  164. write a function that moves through the elements of a container class and, at
  165. some point, needs to save the current position and begin processing elements at
  166. another location. After a period of time, the secondary processing terminates,
  167. at which point flow of control returns to the previous stopping point where the
  168. current position is restored from the iterator object and processing continues.
  169.  
  170. A programmer uses the COOL C++ Control program (CCC), instead of the normal CC
  171. procedure, to control the compilation process. This program provides all of the
  172. capabilities of the original CC program with additional support for the COOL
  173. preprocessor, parameterized types, and the COOL macro language. CCC controls
  174. and invokes the various components of the compilation process. In particular,
  175. however, it looks for command line arguments specific to the parameterized
  176. template process and processes them accordingly as suggested by Stroustrup in
  177. his design paper[2]. Other options and arguments are passed on to the system
  178. C++ compiler control program.
  179. .NH 1
  180. Symbols and Packages
  181. .LP
  182. A package provides a relatively isolated namespace for various COOL components
  183. called symbols.  A symbol that is owned by a particular package is said to be
  184. interned in that package.  In general, the term interned means that a
  185. particular object is uniquely identifiable in some context.  When a symbol is
  186. interned, it becomes uniquely identifiable by the symbol name within a
  187. namespace context.  The package system provides logical groupings of symbols
  188. supporting relationships established between named objects and the values they
  189. contain.  Although the notion of symbols being grouped into packages is fairly
  190. straightforward, the nature of the relationships that can exist between
  191. packages and the way in which they establish a namespace can be quite complex.
  192. COOL provides several kinds of macros to simplify the usage and
  193. manipulation of symbols and packages.
  194.  
  195. A symbol is a data object that defines a relationship between a name, a
  196. package, a value, and a property list. The name is a character string used to
  197. identify the symbol.  Once a name is established for a symbol, it may not be
  198. changed.  The value field is used to refer to some C++ object. Property lists
  199. are lists of alternating names and values. The property list allows the
  200. programmer to associate supplemental attributes with a symbol.  Initially, the
  201. property list for a symbol is empty.
  202.  
  203. The Symbol and Package classes implement the fundamental COOL symbolic
  204. computing support as standard C++ classes. The Symbol class implements the
  205. notion of a symbol that has a name with an optional value and property list.
  206. Symbols are interned into a package, which is merely a mechanism for
  207. establishing separate name spaces.  The Package class implements a package as a
  208. hash table of symbols and includes public member functions for adding,
  209. retrieving, updating, and removing symbols.
  210.  
  211. COOL supports efficient and flexible symbolic computing by providing symbolic
  212. constants and run-time symbol objects[5]. You can create symbolic constants at
  213. compile-time and dynamically create and manipulate symbol objects in a package
  214. at run-time by using any of several simple macros or by directly manipulating
  215. the objects. Symbols and packages in COOL manage error message textual
  216. descriptions with translations, provide polymorphic extensions to C++ for
  217. object type and contents queries, and support sophisticated symbolic computing
  218. not normally available in conventional languages.
  219. .NH 1
  220. Polymorphic Management
  221. .LP
  222. C++ version 2.0 as specified in the AT&T language reference manual[6]
  223. implements virtual member functions that delay the binding of an object to a
  224. specific function implementation until runtime. This delayed (or dynamic)
  225. binding is useful where the type of object might be one of several kinds, all
  226. derived from some common base class but requiring a specialized implementation
  227. of a function. The classic example is that of a graphics editor where, given a
  228. base class graphic_object from which square, circle, and triangle are derived,
  229. specialized virtual member functions to calculate the area are provided. In
  230. such a system, a programmer can write a function that takes a graphic_object
  231. argument and determine its area without knowing which of all the possible kinds
  232. of graphical objects the argument really is.
  233.  
  234. This dynamic binding capability of C++, while powerful and providing greater
  235. flexibility than most other conventional programming languages, is still not
  236. enough for some types of problems. Highly dynamic languages such as 
  237. Lisp allow the programmer to delay almost all decisions until runtime[7]. In
  238. addition, facilities for querying an object at runtime to determine its type or
  239. request a list of all possible member functions available are often present.
  240. These kinds of features are commonly used in many symbolic computing and
  241. complex knowledge-intensive operations management problems tackled today.
  242.  
  243. COOL supports enhanced polymorphic management capabilities with a
  244. programmer-selectable collection of macros, classes, symbolic constants,
  245. run-time symbolic objects, and dynamic packages[1]. This is facilitated by the
  246. Generic class that, combined with macros, symbols, and packages, provides
  247. efficient run-time object type checking, object query, and enhanced polymorphic
  248. functionality unavailable in the C++ language.
  249.  
  250. The Generic class is inherited by most other COOL classes and manipulates
  251. lists of symbols to manage type information. Generic adds run-time type
  252. checking and object queries, formatted print capabilities, and a describe
  253. mechanism to any derived class. The COOL class macro (discussed below)
  254. automatically generates the necessary implementation code for these member
  255. functions in the derived classes. A significant benefit of this common base
  256. class is the ability to declare heterogenous container classes parameterized
  257. over the Generic* type. These classes, combined with the current position and
  258. parameterized iterator class, lets the programmer manipulate collections of
  259. objects of different types in a simple, efficient manner.
  260.  
  261. One of the simplest and most useful features facilitated by Generic is the
  262. runtime type checking capability. The type_of() and is_type_of() virtual member
  263. functions accomplish this kind of run-time type query for an object that is
  264. derived at some point from the COOL Generic class. Type determination and
  265. function dispatch can become quite tedious, however, if there are many types of
  266. objects. Ideally, each would be derived from a common base and include support
  267. for a virtual member function for each important operation that might be
  268. required. However, it is sometimes not feasible to have such a situation,
  269. especially with a high number of objects obtained from several sources. An
  270. alternate scheme similar to the one mentioned above is the type_case macro,
  271. analogous to the C++ switch statement. It gathers all possible type cases and
  272. allows the user to symbolically dispatch on the type of object represented by
  273. the case statements. This automates some of the symbol collection and
  274. manipulation required with the earlier mechanism.
  275.  
  276. The class keyword is implemented as a COOL macro to add symbolic computing
  277. abilities to class definitions.  It takes a standard C++ class definition and,
  278. if the class contains Generic somewhere in its inheritance hierarchy, generates
  279. member functions for support of run-time type checking and query. In addition,
  280. a symbol for the derived Generic class type is added to the COOL global symbol
  281. package SYM. The actual code which is expanded in a class definition and after
  282. a class definition is controlled by the classmac macro discussed below.
  283.  
  284. The classmac macro provides two hooks as a point of customization by
  285. user defined macros. A combination of data members and member functions of a
  286. class definition are passed as arguments to macros that can be changed or
  287. customized by the application programmer. The COOL Generic class uses the data
  288. member hook to implement the map_over_slots() member function. There may be
  289. more than one classmac macro hook specified by the programmer. COOL has
  290. several, and other user-defined macros are simply chained together in a calling
  291. sequence ordered according to the order of definition. Each classmac macro
  292. defines how the class macro should expand the class definition.  The class
  293. macro does not actually generate the code itself. This is defined in
  294. user-modifiable header files that specify a classmac macro. For example, a
  295. general purpose mechanism that automatically creates accessor member functions
  296. to get and set each data member can be created by defining a classmac macro
  297. that is attached to the data member hook of the class macro . No changes to the
  298. COOL preprocessor are required.
  299.  
  300. The member functions added by Generic and the class macro to derived COOL
  301. classes manipulate symbols stored in the global SYM package. These symbols
  302. reflect the inheritance tree for a specific class. They may have optional
  303. property lists containing information associating supported member functions
  304. and their respective argument lists. User-defined classes derived from Generic
  305. are also automatically supported in an identical fashion, resulting in
  306. addition symbols in the global symbol package.  As discussed earlier, these
  307. symbols must have storage allocated for them and code to initialize the package
  308. at program startup time. This is managed by the COOL file symbols.C that should
  309. be compiled and linked with every application that uses COOL. An automated
  310. method for insuring correct package setup and symbol initialization is
  311. accomplished by establishing the correct dependency in an application make
  312. file.
  313. .NH 1
  314. Exceptions
  315. .LP
  316. In COOL, program anomalies are known as exceptions.  An exception can be
  317. an error, but it can also be a problem such as impossible division or
  318. information overflow.  Exceptions can impede the development of object-oriented
  319. libraries.  Exception handling offers a solution by providing a mechanism to
  320. manage such anomalies and simplify program code. The COOL exception
  321. handling scheme is a raise, handle, and proceed mechanism similar to the Common
  322. Lisp Condition System[8]. When a program encounters an anomaly that is
  323. often (but not necessarily) an error, it can:
  324. .ID
  325. \(bu Represent the anomaly in an object called an exception
  326. \(bu Announce the anomaly by raising the exception
  327. \(bu Provide solutions to the anomaly by defining and establishing handlers
  328. \(bu Proceed from the anomaly by invoking a handler function
  329. .DE
  330. The COOL exception handling facility[9] provides an exception class
  331. (Exception), an exception handler class (Excp_Handler), a set of predefined
  332. exception subclasses (Warning,, Fatal, System_Error, System_Signal, and Error),
  333. and a set of predefined exception handler functions. In addition, the macros
  334. EXCEPTION, RAISE, STOP, and VERIFY allow the programmer to easily create and
  335. raise an exception at any point in a program.
  336.  
  337. When an exception is raised (through macros RAISE or STOP, for example), a
  338. search begins for an exception handler that handles this type of exception.  An
  339. exception handler, if found, deals with the exception by calling its exception
  340. handler function. The exception handler function can correct the exception and
  341. continue execution, ignore the exception and resume execution, or end the
  342. program. In COOL, an exception handler for each of the predefined exception
  343. types exists on the global exception handler stack.
  344.  
  345. An exception handler invokes a specific exception handler function for a
  346. specific type of exception.  Handling an exception means proceeding from the
  347. exception.  An exception handler function could report the exception to
  348. standard error and end the program, or drop a core image for use by the
  349. programmer with a debugger. Another way of proceeding is to query the user for
  350. a fix, store the fix in the exception object, and return to where the exception
  351. was raised. When an exception handler object is declared, is is placed on the
  352. top of a global exception handler stack. When an exception is raised, a call
  353. searches for a handler. The handler search starts at the top of the exception
  354. handler stack.
  355.  
  356. There are six predefined exception type classes provided as part of COOL. The
  357. exception class is the base class from which specialized exception subclasses
  358. are derived. Derived from Exception are Warning, System_Signal, Fatal and
  359. Error.  From the Error class, the System_Error and Verify_Error classes are
  360. derived.  The default exception handlers are called only if no other exception
  361. handler is established and available when an exception is raised. COOL
  362. offers users the option of defining their own exception types.  Such types can
  363. be derived from the Exception class of one of the derived exception types. All
  364. user-defined exception classes should have public data slots.
  365.  
  366. The COOL exception handling facility provides several macros which simplify the
  367. process of creating, raising, and manipulating exceptions.  These macros are
  368. implemented with the COOL macro facility. The EXCEPTION macro simplifies the
  369. process of creating an instance of a particular type of exception object. The
  370. RAISE macro allows the programmer to easily raise an exception and search for
  371. an exception handler. The STOP macro is similar to the the RAISE macro, except
  372. that it guarantees to end the program if the exception is not handled. The
  373. VERIFY macro raises an exception if an assertion for some particular expression
  374. evaluates to FALSE.  Finally, the IGNORE_ERRORS macro provides a mechanism to
  375. ignore an exception raised while executing a body of statements.
  376.  
  377. The COOL exception handling mechanism is similar in several ways to that
  378. proposed by Koenig and Stroustrup[10]. Their try statement and catch clauses
  379. can be implemented by using a COOL exception handler with the system functions
  380. \fBsetjmp\fR and \fBlongjmp\fR. In addition, both designs treat exceptions as
  381. objects that are instantiated and passed as arguments to handler functions. The
  382. AT&T proposal proposes a grouping of exception objects as a mechanism for
  383. organizing exceptions into groups similar to the compile-time mechanism for
  384. organizing classes into hierarchies.  COOL, on the other hand, maintains an
  385. exception derivation hierarchy and uses some of the COOL symbolic computing
  386. facilities for run-time type checking and query.  A grouping of exception names
  387. similar to the AT&T proposal is currently being implemented where alias name(s)
  388. may be defined for an exception object. For example, rather than defining a new
  389. exception class derived from Error, an Error exception can be raised with the
  390. specified alias/group name(s) passed as an argument. This is expected to reduce
  391. the need for many different types of exception classes whose only difference is
  392. the type name.
  393. .NH 1
  394. Coding Style and Conventions
  395. .LP
  396. A standard source code style allows several programmers to easily maintain and
  397. understand each other's code because additional semantic information can be
  398. inferred from a section's format and style. In addition, a single style
  399. presents a more coherent, professional software package for potential source
  400. code users. This is particularly important for COOL, since parameterized
  401. templates require complete access to all source code. Finally, one of the
  402. foundations of object-oriented programming is code reuse. This is much easier
  403. if a programmer is able to browse through source code and understand its
  404. organization and layout. The COOL source code addresses the following C++
  405. coding style conventions:
  406. .ID
  407. \(bu Variable and class naming conventions
  408. \(bu Organization and contents of class header files
  409. \(bu Private/Protected/Public data members
  410. \(bu Source code documentation
  411. \(bu Source code indentation and layout
  412. \(bu Error message text resource package
  413. \(bu Regression test suite
  414. \(bu Source code system independence
  415. \(bu Build procedure
  416. .DE
  417. .NH 2
  418. Naming Conventions
  419. .LP
  420. A prime objective for a naming convention is allowing programmers to recognize
  421. what sort of component a name refers to.  Another goal is using meaningful
  422. names, which has not typically been done in C applications.  The following
  423. naming conventions are used throughout the COOL source code. The reader is
  424. strongly encouraged to follow the same guidelines:
  425.  
  426. .RS
  427. \(bu Directory, .C, and .h file names should be the same or close to the 
  428. class being defined and the declaration and implement files should be in a 
  429. single directory. For example, the String class is defined and implemented in 
  430. the files String.h and String.C and contained in the ~COOL/String subdirectory.
  431. .RE
  432.  
  433. .RS
  434. \(bu Class, struct, and typedef names should be capitalized with the words 
  435. separated by underscores:
  436. .ID
  437. class Generic_Window { ... };
  438. struct String_Layout { ... };
  439. typedef int Boolean;
  440. .DE
  441. .RE
  442.  
  443. .RS
  444. \(bu All function names should be lowercase with each word separated by an 
  445. underscore character:
  446. .ID
  447. void my_fun (int foo);
  448. char* get_name (ostream&);
  449. .DE
  450. .RE
  451.  
  452. .RS
  453. \(bu Predicate functions should begin with is_:
  454. .ID
  455. Boolean is_type_of (int);
  456. .DE
  457. .RE
  458.  
  459. .RS
  460. \(bu Variable and data member names should be lowercase with words separated 
  461. by underscores:
  462. .ID
  463. int ref_count;
  464. char* name;
  465. .DE
  466. .RE
  467.  
  468. .RS
  469. \(bu Global and static variables should be appended with _g or _s, 
  470. respectively:
  471. .ID
  472. int node_count_g;
  473. static char* version_s;
  474. .DE
  475. .RE
  476.  
  477. .RS
  478. \(bu Preprocessor statements and MACRO names should be uppercase:
  479. .ID
  480. #define ABS ((x < 0) ? (-x) : x)
  481. .DE
  482. .RE
  483.  
  484. .RS
  485. \(bu Constants (const) declarations should be uppercase:
  486. .ID
  487. const int FALSE=0;
  488. const int TRUE=!FALSE;
  489. .DE
  490. .RE
  491. .NH 2
  492. Class Header File Organization
  493. .LP
  494. All header files defining the structure of a
  495. class or parameterized template should be organized into sections in the
  496. following order:
  497. .ID
  498. \(bu Included files and typedefs necessary for the class.
  499. \(bu Definition of private data members.
  500. \(bu Declaration of private member functions and friends.
  501. \(bu Definition of protected data members.
  502. \(bu Declaration of protected member functions and friends.
  503. \(bu Declaration of public member functions and friends.
  504. \(bu Inline member functions of the class follow the class definition.
  505. \(bu Other member/friend function definitions are in a separate file.
  506. .DE
  507. In general, only the data member definitions and function prototypes of the 
  508. member functions and friend functions should appear in the class construct. 
  509. This separates the implementation from the specification and reduces clutter. 
  510. Define inline functions after the class {...}; statements. In addition, the 
  511. keyword inline should appear in both the class definition and in the actual 
  512. implementation as a documentation aid. The optional private keyword usage is 
  513. explicitly stated. Finally, avoid multiple instances of scoped sections: There 
  514. should be no more than one each of the private, protected, and public labels.
  515. .NH 2
  516. Private, Protected, and Public Data
  517. .LP
  518. In general, class data should be encapsulated in either the private or
  519. protected sections. Data specific to a particular class with no use for
  520. possible derived classes should be located in the private section. Data located
  521. in the protected section might include such things as configuration or
  522. adjustment data members that a derived class might want to monitor or change.
  523. No COOL classes contain public data, and the user should not declare such data.
  524. Aside from being bad object-oriented programming style, classes with public
  525. data cannot be made persistent and stored in the OODB. The one exception to
  526. this standard are the derived exception classes which may require public data
  527. members in order to allow query and/or update of alternate values.
  528. .NH 2
  529. Documentation
  530. .LP
  531. Documentation of all files is very important.  Terseness should be the general
  532. rule for all header files and completeness the rule for all code files.
  533. Parameterized templates have a single header/source file and all documentation
  534. should be located there. If in doubt, more documentation is better than less
  535. documentation. A high-level abstract at the top of each file should provide a
  536. description of the file's functionality.  Class header files should also
  537. contain a brief description of the public interface.
  538.  
  539. Each function in a source code file should have a preceding block comment
  540. specifying the input and output parameters as well as giving a brief synopsis
  541. of the functionality. For complex inline definitions in header files, a block
  542. comment of this type should only be used when the purpose is not obvious
  543. because these comments do not appear in the code file. Since most inline
  544. functions contain trivial code (usually providing an accessor to some private
  545. data member), comment requirements for inline function can be relaxed.
  546.  
  547. All source code should be commented every few source lines. Specifically, large
  548. block comments every 100 lines is unacceptable. No comment should contain
  549. operating system specific names or terms unless that section of code is truly
  550. specific. When this is necessary, the code should be surrounded by conditional
  551. compilation constructs.  These are handled by the preprocessor relative to that
  552. specific operating system.
  553.  
  554. Finally, documentation in the form of a man page should be written for every
  555. class. Layout and organization will be as that with the -man macro package
  556. available for nroff(1)/troff(1). Section names and requirements for a class man
  557. page include Name, Synopsis, Base Class, Friend Classes, Description,
  558. Constructors (public or protected as necessary), Protected Member Functions
  559. (when appropriate), Public Member Functions, Files, See Also, and Bugs (when
  560. necessary). Introductory and high-level material can and should also be
  561. documented.
  562. .NH 2
  563. Source Code Indentation
  564. .LP
  565. Indentation and source code structure is relaxed, but it is suggested that the
  566. programmer use the C++ mode available for GNU Emacs and supplied with COOL. In
  567. general, statements should be restricted to one line with indentation 
  568. reflecting block and scoping visibility. Location of such items as braces,
  569. spacing around parentheses, and so on is left up to the programmer. If the C++
  570. mode is used, whole regions can be marked and indented appropriately, providing
  571. a simple means by which all source code can be brought into the same format.
  572. .NH 2
  573. Error Message Resource Package
  574. .LP
  575. All error message text strings in an application should use the ERR_MSG package
  576. available in COOL. The COOL exception handling scheme automatically uses
  577. this package insuring that all text strings associated with error messages are
  578. stored as the value of a symbol. All error message symbols are
  579. automatically processed and located in one file, thus facilitating easy update
  580. or configuration. In particular, a language translation can be added to the
  581. property list of each symbol entry, providing an efficient and convenient means
  582. for internationalizing the text messages in an application.
  583. .NH 2
  584. Regression Test    Suite
  585. .LP
  586. Each new or modified class contained in or added to COOL must also include
  587. a standalone test program. This should fully exercise all features and
  588. functions and report success or failure via the test macros contained in the
  589. ~COOL/include/test.h header file. This test program is used in regression tests
  590. for new releases and ports to other software platforms to insure a complete and
  591. working implementation.
  592. .NH 2
  593. Source Code System Independence
  594. .LP
  595. COOL places great importance upon system independent code and features. As
  596. such, system-specific functions should be surrounded with #if preprocessor
  597. directives where appropriate. In general small performance sacrifices in
  598. implementation are preferred if system independence and portability is
  599. improved.
  600. .NH 2
  601. Build Procedure
  602. .LP
  603. COOL contains a modified Imake utility from the MIT X11R3 source tape that
  604. implements a system-independent build procedure.  This should be used for all
  605. new classes and source code. Imake provides configuration and rules files for
  606. localization and/or customization of system build utilities and commands to aid
  607. in porting activities to other operating systems and hardware platforms.
  608. .NH 1
  609. Class Hierarchy
  610. .LP
  611. The C++ Object-Oriented Library (COOL) class hierarchy implements a rather
  612. flat inheritance tree, as opposed to the deeply nested SmallTalk model. All
  613. complex classes are derived from the Generic class, to facilitate run-time type
  614. checking and object query Simple classes are not derived from Generic due to
  615. space efficiency concerns. The parameterized container classes all inherit from
  616. a base class that results in shared type-independent code. This reduces code
  617. replication when a particular type of container is parameterized several times
  618. for different objects in a single application. The COOL class hierarchy is as
  619. follows:
  620. .ID
  621. Pair\fR<\fIT1,T2\fR>
  622. Range
  623.     Range\fR<\fIType\fR>
  624. Rational
  625. Complex
  626. Generic
  627.     String
  628.     Gen_String
  629.     Regexp
  630.     Vector
  631.         Vector\fR<\fIType\fR>
  632.             Association\fR<\fIPair\fR<\fIT1,T2\fR>\fR>
  633.     List_Node
  634.         List_Node\fR<\fIType\fR>
  635.     List
  636.         List\fR<\fIType\fR>
  637.     Date_Time
  638.     Timer
  639.     Bit_Set
  640.     Exception
  641.         Warning
  642.         Error
  643.             System_Error
  644.         Fatal
  645.         System_Signal
  646.         Verify_Error
  647.     Excp_Handler
  648.         Jump_Handler
  649.     Hash_Table
  650.         Set
  651.         Hash_Table\fR<\fIKey,Value\fR>
  652.             Package
  653.     Matrix
  654.         Matrix\fR<\fIType\fR>
  655.     Queue
  656.         Queue\fR<\fIType\fR>
  657.     Random
  658.     Stack
  659.         Stack\fR<\fIType\fR>
  660.     Symbol
  661.     Binary_Node
  662.         Binary_Node\fR<\fIType\fR>
  663.     Binary_Tree
  664.         Binary_Tree\fR<\fIType\fR>
  665.             AVL_Tree\fR<\fIType\fR>
  666.     N_Node\fR<\fIType\fR>
  667.     D_Node\fR<\fIType\fR>
  668.     N_Tree\fR<\fIType,Node,nchild\fR>
  669. .DE
  670. .NH 2
  671. String Classes
  672. .LP
  673. The String class provides dynamic, efficient strings for a C++ application. The
  674. intent is to provide efficient char*-like functionality that frees the
  675. programmer from worrying about memory allocation and deallocation problems, yet
  676. retains the speed and compactness of a standard char* implementation. All
  677. typical string operations including concatenation, case-sensitive and
  678. case-insensitive lexical comparison, string search, yank, delete, and
  679. replacement are provided.
  680.  
  681. The Regexp class provides a convenient mechanism to present regular expressions
  682. for complex pattern matching and replacement and utilizes the built-in char*
  683. data type. The Gen_String class provides general-purpose, dynamic strings for a
  684. C++ application with support for reference counting, delayed copy, and regular
  685. expression pattern matching. The intent is to provide a sophisticated character
  686. string function for the application programmer. The Gen_String class combines
  687. the functions of the String and Regexp classes, along with reference counting
  688. and self-garbage collection, to provide advanced character string manipulation.
  689. .NH 2
  690. Number Classes
  691. .LP
  692. The COOL number classes are a collection of numerically-oriented classes that
  693. augment the built-in numerical data types to provide such features as extended
  694. precision, range-checked types, and complex numbers.  The Random class
  695. implements five variations of random number generators. The Complex class
  696. implements the complex number type for C++ and provides basic arithmetic and
  697. trigonometric functions, conversion to and from built-in types, and simple
  698. arithmetic exception handling. The Rational class implements an extended
  699. precision rational data type for inadequate round-off and/or truncation results
  700. from the built-in numerical data types. Finally, the parameterized \fBRange
  701. \fR\fR<\fI\fIType\fR\fR> class enables arbitrary user-defined ranges to be implemented in C++ classes.
  702. Typically, this is used with other number classes to select a range of valid
  703. values for a particular numerical type.
  704. .NH 2
  705. System Interface Classes
  706. .LP
  707. System Interface classes include classes for calculating the date and time in
  708. different timezones and countries and measuring the time duration between two
  709. points in some application program. The Date_Time class executes time
  710. zone-independent date and time functions.  This class also supports all time
  711. zones in the world, along with several special cases requiring alternate
  712. handling based upon political or daylight saving time differences. The Timer
  713. class is publicly derived from Generic and provides an interface to system
  714. timing.  It allows a C++ program to record the time between a reference point
  715. (mark) and now.
  716. .NH 2
  717. Ordered Sequence Classes
  718. .LP
  719. The ordered sequence classes are a collection of basic data structures that
  720. implement sequential access data structures as parameterized classes, thus
  721. allowing the user to customize a generic template to create a user-defined
  722. class. The \fBVector\fR\fR<\fI\fIType\fR\fR> class implements single dimension
  723. vectors of a user-specified type. The \fBStack\fR\fR<\fI\fIType\fR\fR> class
  724. implements a conventional first-in, last-out data structure, similar to the
  725. \fBQueue\fR\fR<\fI\fIType\fR\fR> class but it implements a conventional
  726. first-in, first-out data structure. These two classes each hold a
  727. user-specified data type. The \fBMatrix\fR\fR<\fI\fIType\fR\fR> class
  728. implements two-dimensional arithmetic matrices for a user-specified numeric
  729. data type. The vector, stack, and queue classes can be dynamic in size.
  730. .NH 2
  731. Unordered Sequence Classes
  732. .LP
  733. The unordered sequence classes are a collection of basic data structures that
  734. implement random access data structures as parameterized classes, thus allowing
  735. the user to customize a generic template to create a specific user-defined
  736. class.  The \fBList\fR<\fIType\fR> class implements Common Lisp style lists
  737. providing a collection of member functions for list manipulation and
  738. management.  A list consists of a collection of nodes, each of which contains a
  739. reference count, a pointer to the next node in the list, and a data element of
  740. a user-specified type.  The \fBPair\fR<\fIT1,T2\fR> class implements an
  741. association between one object and another.  The objects may be of different
  742. types, with the first representing the key of the pair and the second
  743. representing the value of the pair. The \fBAssociation\fR<\fIKtype,Vtype\fR>
  744. class is privately derived from the \fBVector\fR<\fIType\fR> class and
  745. implements a collection of pairs. The first of the pair is called the key and
  746. the second of the pair is called the value. The
  747. \fBHash_Table\fR<\fIKtype,VType\fR> class implements hash tables of
  748. user-specified types for the key and the value.
  749. .NH 2
  750. Set Classes
  751. .LP
  752. The set classes implement two basic data structures for random access set
  753. operations as parameterized classes, thus allowing the user to customize a
  754. generic template to create a specific user-defined class.  The
  755. \fBSet\fR<\fIType\fR> class implements random access sets of objects of a
  756. user-specified type using the parameterized type capability of C++. Classical
  757. set operations such as union, intersection, and difference are available. The
  758. \fBSet\fR<\fIType\fR> class is publicly derived from the
  759. \fBHash_Table\fR<\fIKType,VType\fR> class and is dynamic in nature.  The
  760. Bit_Set class implements efficient bit sets. These bits are stored in an
  761. arbitrary length vector of bytes (unsigned char) large enough to represent the
  762. specified number of elements. Elements can be integers, enumerated values,
  763. constant symbols from the enumeration package, or any other type of object or
  764. expression that results in an integral value.
  765. .NH 2
  766. Node and Tree Classes
  767. .LP
  768. The node and tree classes are a collection of basic data structures that
  769. implement several standard tree data structures as parameterized classes, thus
  770. allowing the user to customize a generic template to create a specific
  771. user-defined class.  The \fBBinary_Node\fR<\fIType\fR> class implements
  772. parameterized nodes for binary trees.  The \fBBinary_Tree\fR<\fIType\fR> class
  773. implements simple, dynamic, sorted sequences in a tree where each node has two
  774. subtree pointers. The \fBAVL_Tree\fR<\fIType\fR> class implements
  775. height-balanced, dynamic, binary trees. The \fBAVL_Tree\fR<\fIType\fR> class is
  776. publicly derived from the \fBBinary_Tree\fR<\fIType\fR> class.
  777.  
  778. The \fBN_Node\fR<\fIType,nchild\fR> class implements parameterized nodes of a
  779. static size for n-ary trees. This node class is parameterized for both the type
  780. and some initial number of subtrees that each node may have. The constructors
  781. for the \fBN_Node\fR<\fIType,nchild\fR> class are declared in the public
  782. section to allow the user to create nodes and control the building and
  783. structure of an n-ary tree where the ordering can have a specific meaning, as
  784. with an expression tree. The \fBD_Node\fR<\fIType,nchild\fR> class implements
  785. parameterized nodes of a dynamic size for n-ary trees. This node class is
  786. parameterized for the type and some initial number of subtrees that each node
  787. may have. The \fBD_Node\fR<\fIType,nchild\fR> class is dynamic in the sense
  788. that the number of subtrees allowed for each node is not fixed.
  789. \fBD_Node\fR<\fIType,nchild\fR> uses the \fBVector\fR<\fIType\fR> class,
  790. supporting run-time growth characteristics.
  791.  
  792. The \fBN_Tree\fR<\fINode,Type,nchild\fR> class implements n-ary trees,
  793. providing the organizational structure for a tree (collection) of nodes, but
  794. knowing nothing about the specific type of node used.
  795. \fBN_Tree\fR<\fINode,Type,nchild\fR> is parameterized over a node type, a data
  796. type, and subtree count, where the node specified must have a data member of
  797. the same Type as the tree class. The subtree count indicates the number of
  798. possible subtree pointers (children) from any given node. Two node classes are
  799. provided, but others can also be written.
  800. .NH 1
  801. Status of COOL
  802. .LP
  803. COOL is currently up and running on a Sun SPARCstation 1 (TM) running 
  804. SunOS (TM) 4.x,
  805. .FS
  806. SunOS and SPARCstation 1 are trademarks of Sun Microsystems, Inc.
  807. .FE
  808. a TI System 1500 running TI System V,
  809. a PS/2 model 70 running SCO XENIX\(rg
  810. .FS
  811. XENIX is a registered trademark of Microsoft Corporation.
  812. .FE
  813. 2.3, a PS/2 (TM)
  814. .FS
  815. PS/2 is a trademark of International Business Machines Corporation.
  816. .FE
  817. model 70 running OS/2 1.1, and
  818. a MIPS running RISC/os 4.0. The SPARC and MIPS ports utilize the AT&T C++
  819. translator (cfront) version 2.0 and the XENIX and OS/2 ports utilize the
  820. Glockenspiel translator with the Microsoft C compiler.
  821. .NH 1
  822. References
  823. .LP
  824. .IP [1]
  825. Stanley Lippman,
  826. .I
  827. C++ Primer,
  828. .R
  829. Addison-Wesley, Reading, MA, 1989.
  830. .IP [2]
  831. Texas Instruments Incorporated,
  832. .I
  833. COOL User's Guide,
  834. .R
  835. Information Technology Group, Austin, TX. Internal Original Issue January 1990.
  836. .IP [3]
  837. Bjarne Stroustrup, 
  838. .I
  839. Parameterized Types for C++,
  840. .R
  841. Proceedings of the USENIX C++ Conference, Denver, CO, October 17-21, 1988,
  842. pp. 1-18.
  843. .IP [4]
  844. Mary Fontana, Martin Neath and Lamott Oren,
  845. .I
  846. A Sophisticated C++ Macro Facility,
  847. .R
  848. Information Technology Group, Austin, TX. Internal Original Issue January 1990.
  849. .IP [5]
  850. Mary Fontana, Martin Neath and Lamott Oren,
  851. .I
  852. Symbolic Computing for C++,
  853. .R
  854. Information Technology Group, Austin, TX. Internal Original Issue January 1990.
  855. .IP [6]
  856. AT&T Incorporated,
  857. .I
  858. C++ Language System Release 2.0,
  859. .R
  860. AT&T Product Reference Manual Select Code 307-146, 1989.
  861. .IP [7]
  862. Guy L. Steele Jr,
  863. .I
  864. Common LISP: The Language,
  865. .R
  866. Second Edition, 1990.
  867. .IP [8]
  868. Andy Daniels and Kent Pitman,
  869. .I
  870. Common Lisp Condition System Revision #18,
  871. .R
  872. ANSI X3J13 subcommittee on Error Handling, March 1988.
  873. .IP [9]
  874. Mary Fontana, Martin Neath and Lamott Oren,
  875. .I
  876. Exception Handling in COOL,
  877. .R
  878. Information Technology Group, Austin, TX. Internal Original Issue January 1990.
  879. .IP [10]
  880. Andrew Koenig and Bjarne Stroustrup,
  881. .I
  882. Exception Handling for C++,
  883. .R
  884. C++ At Work Conference, Boston, MA, November 6-8, 1989.
  885.  
  886.